#include "test28_StlConTuple.h"


// 元组和对组
void test28_StlConTuple::classMain()
{
	std::cout << "===test28_StlConTuple===\n";
	//this->testPair();
	this->testTuple();
}

// 对组
void test28_StlConTuple::testPair()
{
	//第一种方法创建一个对组
	std::pair<std::string, int> pair1(std::string("name"), 20);
	std::cout << "第一个值：" << pair1.first << std::endl; //访问pair第一个值
	std::cout << "第二个值：" << pair1.second << std::endl;//访问pair第二个值
	//第二种
	std::pair<std::string, int> pair2 = std::make_pair("name", 30);
	std::cout << "1：" << pair2.first << std::endl;
	std::cout << "2：" << pair2.second << std::endl;
	//pair=赋值
	std::pair<std::string, int> pair3 = pair2;
	std::cout << "第一个值：" << pair3.first << std::endl;
	std::cout << "第二个值：" << pair3.second << std::endl;
}

// 元组
// 元组基本操作 = 在
// 关于元组的使用有三个核心的函数：
//		1. std::make_tuple: 构造元组
//		2. std::get : 获得元组某个位置的值
//		3. std::tie : 元组拆包
void test28_StlConTuple::testTuple()
{
	//name, age, height
	std::tuple<std::string, int, int> t1 = std::make_tuple("tom", 20, 180);
	std::cout << "name: " << std::get<0>(t1) << " age: " << std::get<1>(t1) << " height: " << std::get<2>(t1) << std::endl;


	std::tuple<int, float, std::string> mt1(1,1.10,"直接创建时初始化");
	std::tuple<int, float, std::string> mt2{ 1,1.10,"花括号版" };

	//运行期索引问题
	//std::get<> 依赖一个编译期的常量,所以下面的方式是不合法的：
	//int index = 1;//index为变量,不合法 （C++ 17 引入std::variant<> 处理）
	const int index = 1;//此时可编译通过
	std::get<index>(t1);
	std::cout << "std::get<index>(t1) age:" << std::get<index>(t1) << std::endl;

	//元组合并
	std::tuple<std::string, int, int> t2 = std::make_tuple("jerry", 30, 180);
	std::cout << "std::tuple_size<T>::value=" 
		<< std::tuple_size<std::tuple<std::string, int, int>>::value
		<< std::endl;
	auto new_tuple = std::tuple_cat(t1, t2); // 将多个tuple连接起来形成一个tuple，横向链接
	//auto new_tuple = std::tuple_cat(t1, std::move(t2));
	auto res = test28_StlConTuple::tuple_len(new_tuple);
	std::cout << "tuple_len(new_tuple)=" << res << std::endl;

	// 元组进行拆包/解包 = 访问元素
	std::string name;
	int age;
	int height;
	std::tie(name, age, height) = t1; // 从元素引用中生成一个tuple元组，把元组中的元素自动映射到变量上，元素个数和顺序要对应上
	std::cout << "t1=" << name << ", " << age << ", " << height << std::endl;

	//std::get 除了使用常量获取元组对象外，C++14 增加了使用类型来获取元组中的对象：
	std::tuple<std::string, double, double, int> t("123", 4.5, 6.7, 8);
	std::cout << std::get<std::string>(t) << std::endl;
	//std::cout << std::get<double>(t) << std::endl; // 非法, 引发编译期错误
	std::cout << std::get<3>(t) << std::endl;

}
